#region System
using System;
using System.Collections.Generic;
using System.IO;
using CF.Framework.Engine.Controls;
using CF.Framework.Engine.Drawing;
using CF.Framework.Engine.Misc;
using CF.Framework.Engine.Screens;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
#endregion

namespace CF.Framework.Engine.Screens
{
	/// <summary>
	/// A screen is a single layer that has update and draw logic, and which
	/// can be combined with other layers to build up a complex menu system.
	/// For instance the main menu, the options menu, the "are you sure you
	/// want to quit" message box, and the main game itself are all implemented
	/// as screens.
	/// </summary>
	public abstract partial class GameScreen : GameObject
	{
		#region Fields
		public event EventHandler Exiting;
		#endregion

		#region ctor
		protected GameScreen()
		{
		}
		#endregion

		#region Properties
		public bool IsExiting { get; private set; }
		#endregion

		#region Initialization
		#endregion

		#region Update and Draw
		/// <summary>
		/// Allows the screen to run logic, such as updating the transition position.
		/// Unlike <see cref="HandleInput"/>, this method is called regardless of whether the screen
		/// is active, hidden, or in the middle of a transition.
		/// </summary>
		internal override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
		{
			if (IsExiting)
			{
				// If the screen is going away to die, it should transition off.
				ScreenState = ScreenState.TransitionOff;

				if (!base.UpdateTransition(gameTime, TransitionOffTime, 1))
				{
					// When the transition finishes, remove the screen.
					ScreenManager.RemoveScreen(this);
				}
			}
			
			base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
		}
		#endregion

		#region Public Methods
		/// <summary>
		/// Tells the screen to go away. Unlike <see cref="ScreenManager"/>.RemoveScreen, which
		/// instantly kills the screen, this method respects the transition timings
		/// and will give the screen a chance to gradually transition off.
		/// </summary>
		public void ExitScreen()
		{
			if (TransitionOffTime == TimeSpan.Zero)
			{
				// If the screen has a zero transition time, remove it immediately.
				ScreenManager.RemoveScreen(this);

				if (Exiting != null)
				{
					Exiting(this, EventArgs.Empty);
				}
			}
			else
			{
				// Otherwise flag that it should transition off and then exit.
				IsExiting = true;
			}
		}

		#endregion
	}
}